<html>
    <head>
        <title>其他通用存储库类型</title>
    </head>
    <body>
        <script>
             /*
                        二、其他通用存储库类型  Other Generic Repository Types


                                        标准IRepository<TEntity, TKey>接口公开了标准的IQueryable<TEntity>，你可以使用标准的LINQ方法自由查询。

                                        这对于大多数应用程序来说都很好。

                                        但是，某些ORM提供程序或数据库系统可能不支持标准的IQueryable接口。

                                        如果你想使用这样的提供程序，你不能依赖IQueryable。



                                1、基本存储库  Basic Repository

                                            ABP提供IBasicRepository<TEntity, TPrimaryKey>和IBasicRepository<TEntity>接口来支持此类场景。

                                            你可以扩展这些接口（并且可以选择从BasicRepositoryBase派生）来为你的实体创建自定义存储库。


                                            依赖于IBasicRepository但不依赖于IRepository的优点是可以使用所有数据源，即使它们不支持IQueryable。


                                            主要供应商，如Entity Framework、NHibernate或MongoDB已经支持IQueryable。

                                            因此，使用IRepository是建议的典型应用程序的方式。

                                            然而，可重用模块开发人员可能会考虑IBasicRepository来支持更广泛的数据源。

                                
                                2、只读存储库   Read Only Repositories 

                                            对于那些只想依赖存储库的查询功能的人来说，还有IReadOnlyRepository<TEntity, TKey>和IReadOnlyBasicRepository<Tentity, TKey>接口。

                                            (1)、   IReadOnlyRepository<TEntity, TKey>

                                                         IReadOnlyRepository<TEntity, TKey>派生IReadOnlyBasicRepository<Tentity, TKey>并提供以下属性和方法：

                                                            ①、属性：

                                                                    AsyncExecuter：用于异步执行IQueryable<T>对象，而不依赖于实际的数据库提供程序的服务。

                                                            ②、方法：

                                                                    GetListAsync()
                                                                    GetQueryableAsync()
                                                                    WithDetails() 1个重载
                                                                    WithDetailsAsync()1重载

                                            
                                            (2)、 IReadOnlyBasicRepository<Tentity, TKey>

                                                        而IReadOnlyBasicRepository<Tentity, TKey>提供以下方法：
                                                        
                                                                    GetCountAsync()
                                                                    GetListAsync()
                                                                    GetPagedListAsync()   



                                            ★、只读存储库在EF core 中的行为

                                                       Entity Framework Core只读存储库实现使用EF Core的无跟踪功能。     

                                                       这意味着EF Core更改跟踪器不会跟踪从存储库返回的实体，因为预计你不会更新从只读存储库查询的实体。

                                                       如果你需要跟踪实体，你仍然可以在LINQ表达式上使用AsTrack（）扩展方法，
                                                       
                                                       或在存储库对象上使用EnableTracking()扩展方法（请参阅本文档中的启用/禁用更改跟踪部分）。

                                                    仅当存储库对象被注入只读存储库接口之一（IReadOnlyRepository<...>或IReadOnlyBasicRepository<...>）时，此行为才有效。
                                                    
                                                    如果你注入了标准存储库（例如IRepository<...>），然后将其强制转换为只读存储库接口，则不起作用。
                                 
                                                    
                                3、没有主键的通用存储库

                                            如果你的实体没有Id主键（例如，它可能有一个复合主键），那么你不能使用上面定义的IRepository<TEntity, TKey>（或基本/只读版本）。
                                            
                                            在这种情况下，你可以为你的实体注入和使用IRepository<TEntity>。

                                               
                                              IRepository<TEntity>缺少一些通常与实体的Id属性一起使用的方法，因为在这种情况下实体没有Id属性，所以这些方法不可用。

                                              一个例子是Get方法，它获取一个id并返回具有给定id的实体。但是，你仍然可以使用IQueryable<TEntity>特性通过标准LINQ方法查询实体。
                    */
        </script>
    </body>
</html>